<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
-->
<Module>
	<ModulePrefs title="ActivityStreams Gadget!">
		<Require feature="opensocial"/>
		<Require feature="osapi"/>
		<Require feature="dynamic-height"/>
	</ModulePrefs>
	
	<Content type="html">
	<![CDATA[
		<script>
		/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

function OpenSocialWrapper() {

	// =============================== PEOPLE ===============================

	/*
	 * Loads the owner, the viewer, the owner's friends, and the viewer's
	 * friends.  Response data is put into the variables owner, viewer,
	 * ownerFriends, and viewerFriends, respectively.
	 *
	 * @param callback is the function to return the response to
	 */
	this.loadPeople = function(callback) {
		var batch = osapi.newBatch();
		batch.add('viewer', osapi.people.getViewer());
		batch.add('owner', osapi.people.getOwner());
		batch.add('viewerFriends', osapi.people.getViewerFriends());
		batch.add('ownerFriends', osapi.people.getOwnerFriends());
		batch.execute(callback);
	}

	this.loadViewerFriends = function(callback) {
		osapi.people.getViewerFriends().execute(callback);
	}

	this.loadOwnerFriends = function(callback) {
		osapi.people.getOwnerFriends().execute(callback);
	}

	// ========================= ACTIVITIES =============================
	this.loadActivities = function(callback) {
		var batch = osapi.newBatch();
		batch.add('viewerActivities', osapi.activities.get({userId: '@viewer', groupId: '@self'}));
		batch.add('ownerActivities', osapi.activities.get({userId: '@owner', groupId: '@self'}));
		batch.add('friendActivities', osapi.activities.get({userId: '@viewer', groupId: '@friends'}));
		batch.execute(callback);
	}

	this.loadViewerActivities = function(callback) {
		var req = osapi.activities.get({userId: '@viewer', groupId: '@self'});
		req.execute(callback);
	}

	this.loadViewerFriendsActivities = function(callback) {
		var req = osapi.activities.get({userId: '@viewer', groupId: '@friends'});
		req.execute(this.onLoadActivitiesFriends);
	}

	this.loadOwnerActivities = function(callback) {
		var req = osapi.activities.get({userId: '@owner', groupId: '@self'});
		req.execute(callback);
	}


	// ========================= ACTIVITY STREAMS =============================
	this.loadActivityEntries = function(callback) {
		var batch = osapi.newBatch();
		batch.add('viewerEntries', osapi.activitystreams.get({userId: '@viewer', groupId: '@self'}));
		//batch.add('ownerEntries', osapi.activitystreams.get({userId: '@owner', groupId: '@self'}));
		//batch.add('friendEntries', osapi.activitystreams.get({userId: '@viewer', groupId: '@friends'}));
		batch.execute(callback);
	}

	this.loadViewerActivityEntries = function(callback) {
		var params = {userId: '@viewer', groupId: '@self'};
		osapi.activitystreams.get(params).execute(callback);
	}

	this.loadOwnerActivityEntries = function(callback) {
		var params = {userId: '@owner', groupId: '@self'};
		osapi.activitystreams.get(params).execute(callback);
	}

	this.loadViewerFriendsActivityEntries = function(callback) {
		var params = {userId: '@viewer', groupId: '@friends'};
		osapi.activitystreams.get(params).execute(callback);
	}

	this.postActivityEntry = function(title, content, verb, actorId, actorName, objectName, objectSummary,
									  objectPermalink, objectType, callback) {
		var params = {
			userId: '@viewer',
			groupId: '@self',
			activity: {
				published: '2010-04-27T06:02:36+0000',
				title: title,
				content: content,
				actor: {
					id: actorId,
					displayName: actorName
				},
				verb: verb,
				object: {
					id: new	Date().getTime(),
					displayName: objectName,
					url: objectPermalink,
					objectType: objectType,
					summary: objectSummary
				}
			}
		};
		osapi.activitystreams.create(params).execute(callback);
	}

	this.deleteActivityEntryById = function(activityEntryId, callback) {
		var params = {
			userId: '@viewer',
			groupId: '@self',
			activityId: activityEntryId
		};
		osapi.activitystreams['delete'](params).execute(callback);
	}

	this.getActivityEntryById = function(activityEntryId, callback) {
		var params = {activityId: activityEntryId};
		osapi.activitystreams.get(params).execute(callback);
	}
}

		
		</script>
		<script>
		
		/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

function ActivityStreamsRender() {

	// Private member that wraps the OpenSocial API
	var social = new OpenSocialWrapper();

	// =================== PUBLIC ====================

	// Renders the welcome text (viewer, owner, and friends)
	this.renderWelcome = function(div, callback) {
		social.loadPeople(function(response) {
			viewer = response.viewer;
			owner = response.owner;
			var viewerFriends = response.viewerFriends;
			var ownerFriends = response.ownerFriends;

			var html = '<h1>Welcome ' + viewer.name.formatted + '!</h1>';
			html += 'You are viewing ' + owner.name.formatted + "'s data. <br><br>";
			html += 'Here is a list of your friends: <br>';
			html += '<lu>';
			for (i = 0; i < viewerFriends.list.length; i++) {
				html += '<li>' + viewerFriends.list[i].name.formatted + '</li>';
			}
			html += '</lu>';
			document.getElementById(div).innerHTML = html;
			callback();
		});
	}

	// Renders the activities
	this.renderActivities = function(div, callback) {
		social.loadActivities(function(response) {
			var viewerActivities = response.viewerActivities.list;
			var ownerActivities = response.ownerActivities.list;
			var friendActivities = response.friendActivities.list;

			var html = '<h1>Activities</h1>';
			html += 'Demonstrates use of the Activities service in Apache Shindig.  The ActivityStreams service does not interfere with this service.<br><br>';
			html += 'Activities for you and ' + owner.name.formatted + ':<br>';
			html += "<table border='1'>";
			html += '<tr>';
			html += '<td>Name</td>';
			html += '<td>Title</td>';
			html += '<td>Body</td>';
			html += '<td>Images</td>';
			html += '</tr>';
			html += processActivities(viewerActivities);
			html += processActivities(ownerActivities);
			html += processActivities(friendActivities);
			html += '</table>';
			document.getElementById(div).innerHTML = html;
			callback();
		});
	}

	// Renders activity entries
	this.renderActivityEntries = function(div, callback) {
		social.loadActivityEntries(function(response) {
			var html = '';
			viewerEntries = response.viewerEntries.list;
			//ownerEntries = response.ownerEntries.list;
			//friendEntries = response.friendEntries.list;
			html = '<h2>ActivityEntries</h2>';
			html += processActivityEntries(viewerEntries);
			//html += processActivityEntries(ownerEntries);
			//html += processActivityEntries(friendEntries);
			if (viewerEntries.length == 0) {
				html += '<tr><td>No entries to show!</td></tr>';
			}
			html += '</table><br><br>';
			document.getElementById(div).innerHTML = html;
			callback();
		});
	}

	// ================== PRIVATE =====================

	// Processes activities and returns the rendered HTML
	function processActivities(activities) {
		var html = '';
		for (idx = 0; idx < activities.length; idx++) {
			html += '<tr>';
			html += '<td>' + activities[idx].userId + '</td>';
			html += '<td>' + activities[idx].title + '</td>';
			html += '<td>' + activities[idx].body + '</td>';
			var mediaItems = activities[idx].mediaItems;
			if (mediaItems != null) {
				for (itemIdx = 0; itemIdx < mediaItems.length; itemIdx++) {
					if (mediaItems[itemIdx].type == 'image') {
						html += "<td><img src='" + mediaItems[itemIdx].url + "' width=150 height=150/></td>";
					}
				}
			}
			html += '</tr>';
		}
		return html;
	}

	// Processes activity entries and returns the rendered HTML
	function processActivityEntries(entries) {
		var html = '';
		for (idx = 0; idx < entries.length; idx++) {
			if (entries[idx].object.url && entries[idx].object.url != 'null') {
				html += "<h3><a href='" + entries[idx].object.url + "'>" + entries[idx].title + '</a></h3>';
			} else {
				html += '<h3>' + entries[idx].title + '</h3>';
			}
			html += 'ID: ' + entries[idx].id + '<br>';
			html += 'Actor: ' + entries[idx].actor.displayName + '<br>';
			html += 'Posted: ' + entries[idx].published + '<br>';
			if (entries[idx].content && entries[idx].content != 'null') {
				html += 'Content: ' + entries[idx].content + '<br>';
			}
		}
		return html;
	}
}

		
		</script>
		
		<script type="text/javascript">
			social = new OpenSocialWrapper();
			render = new ActivityStreamsRender();
			
			// TODO: move this stuff into ActivityStreamRender (if you can...)
			// Renders retrieval of an ActivityEntry by ID
			function renderActivityEntryId(div, callback) {
				var html = "<h2>Work with an ActivityEntry</h2>";
				html += "ActivityEntry ID: <input type='text' size=40 id='activityEntryId'>";
				html += "<input type='button' value='Retrieve' onclick='retrieveActivityEntryId()'>";
				html += "<input type='button' value='Delete' onclick='deleteActivityEntryId()'><br>";
				html += "Note: you must be the owner of the ActivityEntry to retrieve it.";
				html += "<textarea id='activityEntryText' cols=75 rows=10>No entry to display...</textarea><br>";
				document.getElementById(div).innerHTML = html;
				callback();
			}
			
			// Deletes the activity entry
			function deleteActivityEntryId() {
				social.deleteActivityEntryById(document.getElementById('activityEntryId').value, function(response) {
					document.getElementById('activityEntryText').value = 'No entry to display...';
					render.renderActivityEntries('activityEntryies', refresh);
				});
			}
			
			// Retrieves the activity entry
			function retrieveActivityEntryId() {
				social.getActivityEntryById(document.getElementById('activityEntryId').value, function(response) {
					document.getElementById('activityEntryText').value = JSON.stringify(response);
				});
			}
			
			// Creation form for activity entry
			function renderCreateActivityEntry(div, callback) {
				var htmlCreateActivityEntry = "<h1>ActivityStreams</h1>";
				htmlCreateActivityEntry += "Demonstrates use of the ActivityStream service in Apache Shindig.  This implementation follows the JSON draft specfication: http://activitystrea.ms/head/json-activity.html<br>";
				htmlCreateActivityEntry += "<h2>Create an ActivityEntry</h2>";
				htmlCreateActivityEntry += "<table>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Title</td>";
				htmlCreateActivityEntry += "<td><input type='text' size=50 id='activityEntryTitle'></td>"
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Body</td>";
				htmlCreateActivityEntry += "<td><input type='text' size=50 id='activityEntryBody'></td>"
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Object Name</td>";
				htmlCreateActivityEntry += "<td><input type='text' size=50 id='activityObjectName'></td>"
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Object Summary</td>";
				htmlCreateActivityEntry += "<td><input type='text' size=50 id='activityObjectSummary'></td>"
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Object Permalink</td>";
				htmlCreateActivityEntry += "<td><input type='text' size=50 id='activityObjectPermalink'></td>"
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "</table>";
				htmlCreateActivityEntry += "<table>";
				htmlCreateActivityEntry += "<tr style='color:blue'>";
				htmlCreateActivityEntry += "<td colspan='2'> Note: Per the ActivityStreams specification, only a single verb and object type are now supported.</td>";
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td>Verbs</td>";
				htmlCreateActivityEntry += "<td>Object Types</td>";
				htmlCreateActivityEntry += "</tr>";
				htmlCreateActivityEntry += "<tr>";
				htmlCreateActivityEntry += "<td><select MULTIPLE id='selectVerbs' size=10>";
				htmlCreateActivityEntry += "<option value='markAsFavorite'>Mark as Favorite</option>";
				htmlCreateActivityEntry += "<option value='startFollowing'>Start Following</option>";
				htmlCreateActivityEntry += "<option value='markAsLiked'>Mark as Liked</option>";
				htmlCreateActivityEntry += "<option value='makeFriend'>Make Friend</option>";
				htmlCreateActivityEntry += "<option value='join'>Join</option>";
				htmlCreateActivityEntry += "<option value='play'>Play</option>";
				htmlCreateActivityEntry += "<option value='post'>Post</option>";
				htmlCreateActivityEntry += "<option value='save'>Save</option>";
				htmlCreateActivityEntry += "<option value='share'>Share</option>";
				htmlCreateActivityEntry += "<option value='tag'>Tag</option>";
				htmlCreateActivityEntry += "<option value='update'>Update</option>";
				htmlCreateActivityEntry += "</select></td>";
				htmlCreateActivityEntry += "<td><select MULTIPLE id='selectObjectTypes' size=10>";
				htmlCreateActivityEntry += "<option value='article'>Article</option>";
				htmlCreateActivityEntry += "<option value='audio'>Audio</option>";
				htmlCreateActivityEntry += "<option value='bookmark'>Bookmark</option>";
				htmlCreateActivityEntry += "<option value='comment'>Comment</option>";
				htmlCreateActivityEntry += "<option value='file'>File</option>";
				htmlCreateActivityEntry += "<option value='folder'>Folder</option>";
				htmlCreateActivityEntry += "<option value='group'>Group</option>";
				htmlCreateActivityEntry += "<option value='list'>List</option>";
				htmlCreateActivityEntry += "<option value='note'>Note</option>";
				htmlCreateActivityEntry += "<option value='person'>Person</option>";
				htmlCreateActivityEntry += "<option value='photo'>Photo</option>";
				htmlCreateActivityEntry += "<option value='photoAlbum'>Photo Album</option>";
				htmlCreateActivityEntry += "<option value='place'>Place</option>";
				htmlCreateActivityEntry += "<option value='playlist'>Playlist</option>";
				htmlCreateActivityEntry += "<option value='product'>Product</option>";
				htmlCreateActivityEntry += "<option value='review'>Review</option>";
				htmlCreateActivityEntry += "<option value='service'>Service</option>";
				htmlCreateActivityEntry += "<option value='status'>Status</option>";
				htmlCreateActivityEntry += "<option value='video'>Video</option>";
				htmlCreateActivityEntry += "</select></td>";
				htmlCreateActivityEntry += "</table>";
				htmlCreateActivityEntry += "<input type='button' value='Submit' onclick='createActivityEntry()'>";
				htmlCreateActivityEntry += "<br><br>";
				document.getElementById(div).innerHTML = htmlCreateActivityEntry;
				callback();
			}
			function createActivityEntry() {
				// Gather selected verbs
				verbOptions = document.getElementById('selectVerbs');
				selVerbs = [];
				count = 0;
				for(i = 0; i < verbOptions.options.length; i++) {
					if(verbOptions.options[i].selected) {
						selVerbs[count] = verbOptions.options[i].value;
						count++;
					}
				}
				
				// Gather selected types
				typeOptions = document.getElementById('selectObjectTypes');
				selTypes = [];
				count = 0;
				for(i = 0; i < typeOptions.options.length; i++) {
					if(typeOptions.options[i].selected) {
						selTypes[count] = typeOptions.options[i].value;
						count++;
					}
				}
				
				var title = blankToNull(document.getElementById('activityEntryTitle').value);
				var body = blankToNull(document.getElementById('activityEntryBody').value)
				var objectName = blankToNull(document.getElementById('activityObjectName').value);
				var objectSummary = blankToNull(document.getElementById('activityObjectSummary').value);
				var objectPermalink = blankToNull(document.getElementById('activityObjectPermalink').value);
				social.postActivityEntry(title, body, selVerbs[0], viewer.id, viewer.name.formatted,
												objectName, objectSummary, objectPermalink, selTypes[0],
												function(response) {
					render.renderActivityEntries('activityEntries', refresh);
				});
			}
			function blankToNull(str) {
				return (str == '' ? null : str);
			}
		
			// Adjusts the window height
			function refresh() {
				gadgets.window.adjustHeight();
			}
		
			// Initializes the gadget
			function init() {
				render.renderWelcome('welcome', refresh);
				render.renderActivities('activities', refresh);
				render.renderActivityEntries('activityEntries', refresh);
				renderActivityEntryId('htmlGetEntry', refresh);
				renderCreateActivityEntry('htmlCreateEntry', refresh);
			}
			
			gadgets.util.registerOnLoadHandler(init);
		</script>
		<div id='welcome'></div>
		<div id='activities'></div>
		<div id='htmlCreateEntry'></div>
		<div id='htmlGetEntry'></div>
		<div id='activityEntries'></div>
	]]>
	</Content>
</Module>